﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Template;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Writers;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IceDog.WebApi.AnythingApi.AppExtensions
{
    /// <summary>
    /// 缓存swagger.json文件扩展
    /// </summary>
    public static class CacheSwaggerFileExtensions
    {

        /// <summary>
        /// 
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="routeTemplate"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseCacheSwaggerJsonFile(this IApplicationBuilder builder,string routeTemplate)
        {
            var requestMatcher = new TemplateMatcher(TemplateParser.Parse(routeTemplate), new RouteValueDictionary());
            
            builder.MapWhen(context =>
            {
                //定义匹配分支条件
                var flag = context.Request.Path.Value.EndsWith(".json");
                var routeValues = new RouteValueDictionary();
                return flag;
            }, builder =>
            {
                //往管道里面注入处理中间件
                builder.Use(async (context, next) =>
                {
                    var routeValues = new RouteValueDictionary();
                    requestMatcher.TryMatch(context.Request.Path, routeValues);
                    if (!routeValues.ContainsKey("documentName"))
                    {
                        return;
                    }
                    var swaggerProvider = builder.ApplicationServices.GetRequiredService<SwaggerGenerator>();
                    var swagger = swaggerProvider.GetSwagger(routeValues["documentName"].ToString());
                    var response = context.Response;
                    response.StatusCode = 200;
                    response.ContentType = "application/json;charset=utf-8";
                    using (var textWriter = new StringWriter(CultureInfo.InvariantCulture))
                    {
                        var jsonWriter = new OpenApiJsonWriter(textWriter);
                        swagger.SerializeAsV3(jsonWriter);
                        await response.WriteAsync(textWriter.ToString(), new UTF8Encoding(false));
                    }
                });
            });
            return builder;
        }

    }
}
